#ifndef SERVER_H
#define SERVER_H

#include <QObject>
#include <QHttpServer>
#include <QProtobufSerializer>
#include <QWebSocketServer>
#include <QFileInfo>
#include <QFile>
#include <QPixmap>
#include <QIcon>
#include <QResource>


// 从 __FILE__ 中提取文件名 -- 下面两种方式都可以
static inline QString getFileName(const QString& path){
    QFileInfo fileInfo(path);
    return fileInfo.fileName();
}

#define TAG QString("[%1:%2]").arg(getFileName(__FILE__), QString::number(__LINE__))
#define LOG() qDebug().noquote() << TAG

// 把时间戳转为标准时间
static inline QString formatTime(int64_t timestamp){
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(timestamp);
    return dateTime.toString("MM-dd HH::mm::ss");
}

// 获取时间戳
static inline int64_t getTime(){
    return QDateTime::currentSecsSinceEpoch();
}

// 根据 QByteArray 转成 QIcon
static inline QIcon makeIcon(const QByteArray& byteArray){
    QPixmap pixmap;
    pixmap.loadFromData(byteArray);
    QIcon icon(pixmap);
    return icon;
}

// 读写文件 -- 从指定文件读取所有二进制内容得到 QByteArray
static inline QByteArray loadFileToByteArray(const QString& path){
    LOG()<<path;
    QFile file(path);
    bool ok = file.open(QFile::ReadOnly);
    if(!ok){
        LOG() << "文件打开失败";
        return QByteArray();
    }
    QByteArray content = file.readAll();
    file.close();
    return content;
}

static inline QPixmap getRoundRectPixmap(QPixmap srcPixMap, const QSize & size, int radius){
    // 不处理空数据或者错误数据
    if (srcPixMap.isNull()) return srcPixMap;

    // 获取图片尺寸
    int imageWidth = size.width(), imageHeight = size.height();

    // 处理大尺寸的图片,保证图片显示区域完整
    QPixmap newPixMap = srcPixMap.scaled(imageWidth, (imageHeight == 0 ? imageWidth : imageHeight),Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    QPixmap destImage(imageWidth, imageHeight);
    destImage.fill(Qt::transparent);
    QPainter painter(&destImage);
    // 抗锯齿
    painter.setRenderHints(QPainter::Antialiasing, true);
    // 图片平滑处理
    painter.setRenderHints(QPainter::SmoothPixmapTransform, true);
    // 将图片裁剪为圆角
    QPainterPath path;
    QRect rect(0, 0, imageWidth, imageHeight);
    path.addRoundedRect(rect, radius, radius);
    painter.setClipPath(path);
    painter.drawPixmap(0, 0, imageWidth, imageHeight, newPixMap);

    return destImage;
}



static inline QByteArray pixmapToByteArray(const QPixmap& pixmap, const char* format = "PNG") {
    QByteArray bytes;
    QBuffer buffer(&bytes);
    buffer.open(QIODevice::WriteOnly);
    pixmap.save(&buffer, format); // 可选 "PNG" 或 "JPG"
    buffer.close();
    return bytes;
}

// 把 QByteArray 的内容写入指定文件
static inline void writeByteArrayToFile(const QString& path, const QByteArray& content){
    QFile file(path);
    bool ok = file.open(QFile::WriteOnly);
    if(!ok){
        LOG() << "文件打开失败";
        return ;
    }
    file.write(content);
    file.flush();
    file.close();
}


/* ------------------------- HTTP 服务器 ------------------------- */
class HttpServer : public QObject {
    Q_OBJECT

private:
    static HttpServer* instance;
    HttpServer() {}

    QHttpServer httpServer;
    QProtobufSerializer serializer;

public:
    static HttpServer* getInstance();

    // 通过这个函数, 针对 HTTP Server 进行初始化 (绑定端口, 配置路由....)
    bool init();

    /* ------------------------- 主界面设计 ------------------------- */
    QHttpServerResponse getUserInfo(const QHttpServerRequest& req);         // 获取个人用户信息
    QHttpServerResponse getFriendList(const QHttpServerRequest& req);       // 获取好友列表
    QHttpServerResponse getChatSessionList(const QHttpServerRequest& req);  // 获取会话列表
    QHttpServerResponse getApplyList(const QHttpServerRequest& req);        // 获取好友申请列表
    QHttpServerResponse getRecent(const QHttpServerRequest& req);           // 获取指定会话的最近消息列表

    // 处理发送消息
    QHttpServerResponse newMessage(const QHttpServerRequest& req);

    /* ------------------------- 用户个人信息 ------------------------- */
    QHttpServerResponse setNickname(const QHttpServerRequest& req);         // 修改用户昵称
    QHttpServerResponse setDesc(const QHttpServerRequest& req);             // 修改用户签名
    QHttpServerResponse getPhoneVerifyCode(const QHttpServerRequest& req);  // 获取短信验证码
    QHttpServerResponse setPhone(const QHttpServerRequest& req);            // 修改手机号
    QHttpServerResponse setAvatar(const QHttpServerRequest& req);           // 修改头像

    /* ------------------------- 好友处理 ------------------------- */
    QHttpServerResponse removeFriend(const QHttpServerRequest& req); // 删除好友
    QHttpServerResponse addFriendApply(const QHttpServerRequest& req); // 添加好友申请
    QHttpServerResponse addFriendProcess(const QHttpServerRequest& req); // 添加好友申请的处理

    /* ------------------------- 会话创建 ------------------------- */
    QHttpServerResponse createChatSession(const QHttpServerRequest& req);   // 创建会话
    QHttpServerResponse getChatSessionMember(const QHttpServerRequest& req);    // 获取会话成员列表

    /* ------------------------- 搜索处理 ------------------------- */
    QHttpServerResponse searchFriend(const QHttpServerRequest& req);    // 搜索好友
    QHttpServerResponse searchHistory(const QHttpServerRequest& req);   // 搜索历史消息
    QHttpServerResponse getHistory(const QHttpServerRequest& req);      // 按时间搜索历史消息


    /* ------------------------- 登录注册 ------------------------- */
    QHttpServerResponse usernameLogin(const QHttpServerRequest& req); // 基于用户名密码登录
    QHttpServerResponse usernameRegister(const QHttpServerRequest& req); // 基于用户名密码注册
    QHttpServerResponse phoneLogin(const QHttpServerRequest& req);    // 手机号登录
    QHttpServerResponse phoneRegister(const QHttpServerRequest& req);   // 手机号注册

    /* ------------------------- 其他 ------------------------- */
    QHttpServerResponse getSingleFile(const QHttpServerRequest& req);   // 获取单个文件
    QHttpServerResponse recognition(const QHttpServerRequest& req);     // 语音转文字
};



/* ------------------------- WebSocket 服务器 ------------------------- */
class WebsocketServer : public QObject {
    Q_OBJECT

private:
    static WebsocketServer* instance;
    WebsocketServer() : websocketServer("websocket server", QWebSocketServer::NonSecureMode) {}

    QWebSocketServer websocketServer;
    QProtobufSerializer serializer;

    int messageIndex = 0;

public:
    static WebsocketServer* getInstance();
    bool init();

signals:
    void sendTextResp();
    void sendImageResp();
    void sendFileResp();
    void sendSpeechResp();
    void sendFriendRemove();
    void sendAddFriendApply();
    void sendAddFriendProcess(bool agree);
    void sendCreateChatSession();
};

#endif // SERVER_H
